package com.java.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

/**
 * @program: java_basic_knowledge
 * @description:
 * @author: CaoYong
 * @create: 2021-04-07 11:14
 **/
public class AnnotationKnowledge {

    /**
     * 注解就是给程序添加一些信息，用@开头，与注释不同的是这些信息可以被编译器,程序运行时和其他工具使用，用于增强或修改程序的行为
     */
    public static void whatIsAnnotation() {

        /**
         * 定义注解类似于定义接口，只不过用@interface修饰，此外定义注解还需要两个元注解@Target和@Retention
         * @Target 表示注解的作用目标 可选值包括（TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE)
         * @Retention 表示注解信息保留到什么时候，值只能取一个，可选值包括（SOURCE, CLASS, RUNTIME), 默认为CLASS
         * @Documented 表示注解信息包含到生成的文档只中
         */
//        @Target(ElementType.METHOD)
//        @Retention(RetentionPolicy.SOURCE)
//        public @interface Override {
//              boolean optional() default false; // 可以通过default设置默认值，但不能为null
//        }

    }

    public static void howToGetAnnotation() {

    }

    public static void howToCreateAnnotation() {

    }

    public static void howToUseAnnotation() throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Student student = new Student("张三", simpleDateFormat.parse("2000-12-1"), 89.5d);
        System.out.println(format(student));
    }

    public static void main(String[] args) throws Exception{
        howToUseAnnotation();
    }

    private static String format(Object object) {

        try {
            Class<?> aClass = object.getClass();
            StringBuilder sb = new StringBuilder();
            Field[] fields = aClass.getDeclaredFields();
            for (Field field : fields) {
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }
                Label label = field.getAnnotation(Label.class);
                String name = label != null ? label.value() : field.getName();
                Object value = field.get(object);
                if(value != null && field.getType() == Date.class) {
                    value = formatDate(field, value);
                }
                sb.append(name + ":" + value + "\n");
            }
            return sb.toString();
        } catch (IllegalAccessException e) {
            throw new RuntimeException();
        }
    }

    private static Object formatDate(Field field, Object value) {
        Format format = field.getAnnotation(Format.class);
        if (format != null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format.pattern());
            simpleDateFormat.setTimeZone(TimeZone.getTimeZone(format.timezone()));
            return simpleDateFormat.format(value);
        }
        return value;
    }

}
